﻿/*
 * FormMain - Quinctia 的主窗体
 * 代码功能：项目 Quinctia 的主窗体界面，总控制台
 * 作者名称：Tsybius2014
 * 创建时间：2015年1月17日
 * 最后修改：2015年1月17日
 * */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Quinctia
{
    public partial class FormMain : Form
    {
        #region 初始化

        public FormMain()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Load函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormMain_Load(object sender, EventArgs e)
        {
            SetDataGridView();

            //读取程序配置
            ConfigHelper.QuinctiaConfig.RefreshQuinctiaConfig();

            //需要提示语言选择框的情况
            if(ConfigHelper.QuinctiaConfig.GetNeedLanguagePrompt())
            {
                //读取语言配置
                ConfigHelper.LanguageConfig.RefreshLanguageConfig(ConfigHelper.QuinctiaConfig.GetCurrLangPath());
                
                //提示语言选择框
                AssistantForms.FormSelectLanguage frmSelectLanguage = new AssistantForms.FormSelectLanguage(ConfigHelper.QuinctiaConfig.dtLang);
                if (frmSelectLanguage.ShowDialog() == DialogResult.OK)
                {
                    //修改当前配置
                    ConfigHelper.QuinctiaConfig.SetLanguage(frmSelectLanguage.GetLanguageFile(), frmSelectLanguage.NeedPrompt());
                }
            }

            //读取最新的语言配置
            ConfigHelper.LanguageConfig.RefreshLanguageConfig(ConfigHelper.QuinctiaConfig.GetCurrLangPath());

            SetWordsFromLangConfig();

            //程序右下角显示版本号
            tsslProgramInfo.Text = "V" + System.Diagnostics.FileVersionInfo.GetVersionInfo(Application.ExecutablePath).FileVersion;
        }

        private void SetDataGridView()
        {
            //单击单元格时选取整行
            this.dgvReferenceData.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;

            this.dgvReferenceData.AllowUserToAddRows = false;
            this.dgvReferenceData.AllowUserToDeleteRows = false;
            this.dgvReferenceData.AllowUserToResizeRows = false;
        }

        /// <summary>
        /// 设置语言
        /// </summary>
        private void SetWordsFromLangConfig()
        {
            this.Text = ConfigHelper.LanguageConfig.langFormMain.strTitle;

            this.tsmiFile.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileText;
            this.tsmiNew.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileNew;
            this.tsmiOpen.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileOpen;
            this.tsmiSave.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileSave;
            this.tsmiGenerate.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileGenerate;
            this.tsmiConfig.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileConfig;
            this.tsmiExit.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemFileExit;

            this.tsmiOther.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemHelpText;
            this.tsmiHelp.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemHelpHelp;
            this.tsmiAbout.Text = ConfigHelper.LanguageConfig.langFormMain.strToolStripMenuItemHelpAbout;

            this.grbCurrData.Text = ConfigHelper.LanguageConfig.langFormMain.strGroupBoxCurrDataText;

            this.grbAddData.Text = ConfigHelper.LanguageConfig.langFormMain.strGroupBoxAddDataText;
            this.btnAddMonograph.Text = ConfigHelper.LanguageConfig.langFormMain.strAddMonographText;
            this.btnAddMonographContribution.Text = ConfigHelper.LanguageConfig.langFormMain.strAddMonographContributionText;
            this.btnAddSerial.Text = ConfigHelper.LanguageConfig.langFormMain.strAddSerialText;
            this.btnAddSerialContribution.Text = ConfigHelper.LanguageConfig.langFormMain.strAddSerialContributionText;
            this.btnAddPatentDocumentation.Text = ConfigHelper.LanguageConfig.langFormMain.strAddPatentDocumentationText;
            this.btnAddElectronicDocument.Text = ConfigHelper.LanguageConfig.langFormMain.strAddElectronicDocumentText;

            this.grbOtherOper.Text = ConfigHelper.LanguageConfig.langFormMain.strGroupBoxOtherOperText;
            this.btnClear.Text = ConfigHelper.LanguageConfig.langFormMain.strClearSelectedText;
            this.btnModifySelected.Text = ConfigHelper.LanguageConfig.langFormMain.strModifySelectedText;
            this.btnDeleteSelected.Text = ConfigHelper.LanguageConfig.langFormMain.strDeleteSelectedText;
            this.btnGenerate.Text = ConfigHelper.LanguageConfig.langFormMain.strGenerateText;

        }

        #endregion

        #region 菜单事件

        /// <summary>
        /// 菜单按钮：新建工程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiNew_Click(object sender, EventArgs e)
        {
            if (isModified == true)
            {
                if (MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_INFO_GIVE_UP_CHANGED).ToString(), "", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK)
                {
                    return;
                }
            }

            llReferences.Clear();
            RefreshReferenceData();
            isModified = false;
        }

        /// <summary>
        /// 菜单按钮：打开工程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiOpen_Click(object sender, EventArgs e)
        {
            //打开提示窗
            OpenFileDialog ofdReadReferenceList = new OpenFileDialog();

            ofdReadReferenceList.AutoUpgradeEnabled = true;
            ofdReadReferenceList.CheckFileExists = true;
            ofdReadReferenceList.ReadOnlyChecked = false;
            ofdReadReferenceList.Multiselect = false;
            ofdReadReferenceList.FileName = "";
            ofdReadReferenceList.Filter = "XML文件|*.xml";
            ofdReadReferenceList.Title = "打开";

            //默认路径
            if (Directory.Exists(Application.StartupPath + "\\SavFiles"))
            { 
                ofdReadReferenceList.InitialDirectory = Application.StartupPath + "\\SavFiles";
            }

            if (ofdReadReferenceList.ShowDialog() == DialogResult.OK)
            {
                if (isModified == true)
                {
                    if (MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_INFO_GIVE_UP_CHANGED).ToString(), "", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK)
                    {
                        return;
                    }
                }

                SaveAndLoad.ReadRefListFromXML(llReferences, ofdReadReferenceList.FileName);
                RefreshReferenceData();
                isModified = false;
            }
            else
            {
                return;
            }
        }

        /// <summary>
        /// 菜单按钮：保存工程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiSave_Click(object sender, EventArgs e)
        {
            //保存提示窗
            SaveFileDialog sfdSaveReferenceList = new SaveFileDialog();

            sfdSaveReferenceList.OverwritePrompt = true;
            sfdSaveReferenceList.Filter = "XML|*.xml";

            //默认路径
            if (Directory.Exists(Application.StartupPath + "\\SavFiles"))
            {
                sfdSaveReferenceList.InitialDirectory = Application.StartupPath + "\\SavFiles";
            }

            if (sfdSaveReferenceList.ShowDialog() == DialogResult.OK)
            {
                SaveAndLoad.WriteRefListToXML(llReferences, sfdSaveReferenceList.FileName);
            }
            else
            {
                return;
            }

            isModified = false;
        }

        /// <summary>
        ///  菜单按钮：生成清单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiGenerate_Click(object sender, EventArgs e)
        {
            GenerateRefList();
        }

        /// <summary>
        /// 菜单按钮：设置语言
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiConfig_Click(object sender, EventArgs e)
        {
            //提示语言选择框
            AssistantForms.FormSelectLanguage frmSelectLanguage = new AssistantForms.FormSelectLanguage(ConfigHelper.QuinctiaConfig.dtLang);
            if (frmSelectLanguage.ShowDialog() == DialogResult.OK)
            {
                if (frmSelectLanguage.GetLanguageFile() != ConfigHelper.QuinctiaConfig.GetCurrLangPath() ||
                    frmSelectLanguage.NeedPrompt() != ConfigHelper.QuinctiaConfig.GetNeedLanguagePrompt())
                {
                    MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_LANG_CHANGED).ToString());

                    //修改当前配置
                    ConfigHelper.QuinctiaConfig.SetLanguage(frmSelectLanguage.GetLanguageFile(), frmSelectLanguage.NeedPrompt());
                }
            }
        }

        /// <summary>
        /// 菜单按钮：退出程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// 打开帮助文档所在的文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiHelp_Click(object sender, EventArgs e)
        {
            string strFolderPath = Application.StartupPath + "\\HelpDocumentation";
            System.Diagnostics.Process.Start("explorer.exe", strFolderPath);
        }

        /// <summary>
        /// 关于文档
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiAbout_Click(object sender, EventArgs e)
        {
            AssistantForms.FormAbout frmAbout = new AssistantForms.FormAbout();
            frmAbout.ShowDialog();
        }

        #endregion

        #region 列表

        /// <summary>
        /// 著录链表
        /// </summary>
        LinkedList<Reference> llReferences = new LinkedList<Reference>();
        
        /// <summary>
        /// 指示著录链表自读取后或上次保存后是否经过修改
        /// </summary>
        bool isModified = false;

        /// <summary>
        /// 根据著录链表，更新表格控件 dgvReferenceData
        /// </summary>
        private void RefreshReferenceData()
        {
            DataTable dtReferenceString = new DataTable();
            dtReferenceString.Columns.Add();

            foreach (Reference refNode in llReferences)
            {
                dtReferenceString.Rows.Add(refNode.ToString());
            }

            dgvReferenceData.DataSource = dtReferenceString;

            //设置表格列宽自适应
            dgvReferenceData.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }

        //为表格控件显示行号
        private void dgvReferenceData_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            System.Drawing.Rectangle rectangle =
                new System.Drawing.Rectangle(
                    e.RowBounds.Location.X, 
                    e.RowBounds.Location.Y, 
                    dgvReferenceData.RowHeadersWidth - 4,
                    e.RowBounds.Height);

            TextRenderer.DrawText(
                e.Graphics, 
                (e.RowIndex + 1).ToString(), 
                dgvReferenceData.RowHeadersDefaultCellStyle.Font,
                rectangle, 
                dgvReferenceData.RowHeadersDefaultCellStyle.ForeColor,
                TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }

        #endregion

        #region 按钮事件

        /// <summary>
        /// 添加专著
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddMonographs_Click(object sender, EventArgs e)
        {
            FunctionForms.FormMonograph formMonograph = new FunctionForms.FormMonograph();
            if (formMonograph.ShowDialog() == DialogResult.OK)
            {
                llReferences.AddLast(formMonograph.refMonograph);
                RefreshReferenceData();
                isModified = true;
            }
        }

        /// <summary>
        /// 添加专著析出文献
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddMonographContribution_Click(object sender, EventArgs e)
        {
            FunctionForms.FormMonographContribution formMonographContribution = new FunctionForms.FormMonographContribution();
            if (formMonographContribution.ShowDialog() == DialogResult.OK)
            {
                llReferences.AddLast(formMonographContribution.refMonographContirbution);
                RefreshReferenceData();
                isModified = true;
            }
        }

        /// <summary>
        /// 添加连续出版物
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddSerial_Click(object sender, EventArgs e)
        {
            FunctionForms.FormSerial formSerial = new FunctionForms.FormSerial();
            if (formSerial.ShowDialog() == DialogResult.OK)
            {
                llReferences.AddLast(formSerial.refSerial);
                RefreshReferenceData();
                isModified = true;
            }
        }

        /// <summary>
        /// 添加连续出版物析出文献
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddSerialContribution_Click(object sender, EventArgs e)
        {
            FunctionForms.FormSerialContribution formSerialContribution = new FunctionForms.FormSerialContribution();
            if (formSerialContribution.ShowDialog() == DialogResult.OK)
            {
                llReferences.AddLast(formSerialContribution.refSerialContribution);
                RefreshReferenceData();
                isModified = true;
            }
        }

        /// <summary>
        /// 添加专利文献
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddPatentDocumentation_Click(object sender, EventArgs e)
        {
            FunctionForms.FormPatentDocument formPatentDocumentation = new FunctionForms.FormPatentDocument();
            if (formPatentDocumentation.ShowDialog() == DialogResult.OK)
            {
                llReferences.AddLast(formPatentDocumentation.refPatentDocument);
                RefreshReferenceData();
                isModified = true;
            }
        }

        /// <summary>
        /// 添加电子文献
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddElectronicDocument_Click(object sender, EventArgs e)
        {
            FunctionForms.FormElectronicDocument formElectronicDocument = new FunctionForms.FormElectronicDocument();
            if (formElectronicDocument.ShowDialog() == DialogResult.OK)
            {
                llReferences.AddLast(formElectronicDocument.refElectronicDocument);
                RefreshReferenceData();
                isModified = true;
            }
        }

        /// <summary>
        /// 修改选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnModifySelected_Click(object sender, EventArgs e)
        {
            if (dgvReferenceData.SelectedRows.Count == 0)
            {
                MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_NO_ROW_SELECTED).ToString());
                return;
            }

            int intNum = dgvReferenceData.SelectedRows[0].Index;
            LinkedListNode<Reference> llnTemp = llReferences.First;
            while (intNum != 0)
            {
                llnTemp = llnTemp.Next;
                intNum--;
            }

            //用新修改的条目替换指定条目
            switch (llnTemp.Value.strRefType)
            {
                case ConstantDict.CONSTANT_REF_TYPE_MONOGRAPH:
                    {
                        FunctionForms.FormMonograph formMonograph = new FunctionForms.FormMonograph(llnTemp.Value as RefMonograph);
                        if (formMonograph.ShowDialog() == DialogResult.OK)
                        {
                            llnTemp.Value = formMonograph.refMonograph;
                            RefreshReferenceData();
                            isModified = true;
                        }
                    }
                    break;
                case ConstantDict.CONSTANT_REF_TYPE_MONOGRAPH_CONTRIBUTION:
                    {
                        FunctionForms.FormMonographContribution formMonographContribution = new FunctionForms.FormMonographContribution(llnTemp.Value as RefMonographContribution);
                        if (formMonographContribution.ShowDialog() == DialogResult.OK)
                        {
                            llnTemp.Value = formMonographContribution.refMonographContirbution;
                            RefreshReferenceData();
                            isModified = true;
                        }
                    }
                    break;
                case ConstantDict.CONSTANT_REF_TYPE_SERIAL:
                    {
                        FunctionForms.FormSerial formSerial = new FunctionForms.FormSerial(llnTemp.Value as RefSerial);
                        if (formSerial.ShowDialog() == DialogResult.OK)
                        {
                            llnTemp.Value = formSerial.refSerial;
                            RefreshReferenceData();
                            isModified = true;
                        }
                    }
                    break;
                case ConstantDict.CONSTANT_REF_TYPE_SERIAL_CONTRIBUTION:
                    {
                        FunctionForms.FormSerialContribution formSerialContribution = new FunctionForms.FormSerialContribution(llnTemp.Value as RefSerialContribution);
                        if (formSerialContribution.ShowDialog() == DialogResult.OK)
                        {
                            llnTemp.Value = formSerialContribution.refSerialContribution;
                            RefreshReferenceData();
                            isModified = true;
                        }
                    }
                    break;
                case ConstantDict.CONSTANT_REF_TYPE_PATENT_DOCUMENT:
                    {
                        FunctionForms.FormPatentDocument formPatentDocumentation = new FunctionForms.FormPatentDocument(llnTemp.Value as RefPatentDocument);
                        if (formPatentDocumentation.ShowDialog() == DialogResult.OK)
                        {
                            llnTemp.Value = formPatentDocumentation.refPatentDocument;
                            RefreshReferenceData();
                            isModified = true;
                        }
                    }
                    break;
                case ConstantDict.CONSTANT_REF_TYPE_ELECTRONIC_DOCUMENT:
                    {
                        FunctionForms.FormElectronicDocument formElectronicDocument = new FunctionForms.FormElectronicDocument(llnTemp.Value as RefElectronicDocument);
                        if (formElectronicDocument.ShowDialog() == DialogResult.OK)
                        {
                            llnTemp.Value = formElectronicDocument.refElectronicDocument;
                            RefreshReferenceData();
                            isModified = true;
                        }
                    }
                    break;
            }
        }

        /// <summary>
        /// 删除选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDeleteSelected_Click(object sender, EventArgs e)
        {
            if (dgvReferenceData.SelectedRows.Count == 0)
            {
                MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_NO_ROW_SELECTED).ToString());
                return;
            }

            int intNum = dgvReferenceData.SelectedRows[0].Index;
            LinkedListNode<Reference> llnTemp = llReferences.First;
            while (intNum != 0)
            {
                llnTemp = llnTemp.Next;
                intNum--;
            }

            llReferences.Remove(llnTemp);
            isModified = true;
            RefreshReferenceData();
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            llReferences.Clear();
            RefreshReferenceData();
            isModified = true;
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            GenerateRefList();
        }

        /// <summary>
        /// 生成引用清单
        /// </summary>
        private void GenerateRefList()
        {
            int counter = 1;

            StringBuilder sbRefList = new StringBuilder();

            LinkedListNode<Reference> llnTemp = llReferences.First;
            while (llnTemp != null)
            {
                sbRefList.Append(string.Format("[{0}] ", counter.ToString()));
                sbRefList.Append(llnTemp.Value.ToString());
                sbRefList.Append("\r\n");
                llnTemp = llnTemp.Next;
                counter++;
            }

            AssistantForms.FormRefList formRefList = new AssistantForms.FormRefList(sbRefList.ToString());
            formRefList.ShowDialog();
        }

        /// <summary>
        /// 选中条目上移
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUp_Click(object sender, EventArgs e)
        {
            if (dgvReferenceData.SelectedRows.Count == 0)
            {
                MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_NO_ROW_SELECTED).ToString());
                return;
            }

            int intNum = dgvReferenceData.SelectedRows[0].Index;
            if (intNum == 0)
            {
                MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_TOP_ROW_CANNOT_UP_MORE).ToString());
                return;
            }

            LinkedListNode<Reference> llnCurr = llReferences.First;
            int intTmp = intNum;
            while (intTmp != 0)
            {
                llnCurr = llnCurr.Next;
                intTmp--;
            }

            //交换位置
            Reference refCurrValue = llnCurr.Value;
            Reference refPrevValue = llnCurr.Previous.Value;
            llnCurr.Previous.Value = refCurrValue;
            llnCurr.Value = refPrevValue;
            
            //刷新表格
            RefreshReferenceData();

            //选中交换前选中的行（否则会默认选中第0行）
            dgvReferenceData.Rows[intNum - 1].Selected = true;

            isModified = true;
        }

        /// <summary>
        /// 选中条目下移
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDown_Click(object sender, EventArgs e)
        {
            if (dgvReferenceData.SelectedRows.Count == 0)
            {
                MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_NO_ROW_SELECTED).ToString());
                return;
            }

            int intNum = dgvReferenceData.SelectedRows[0].Index;
            if (intNum == dgvReferenceData.Rows.Count - 1)
            {
                MessageBox.Show(new ErrorManip.ErrorData(ConstantDict.CONSTANT_ERROR_BOTTOM_ROW_CANNOT_DOWN_MORE).ToString());
                return;
            }

            LinkedListNode<Reference> llnCurr = llReferences.First;
            int intTmp = intNum;
            while (intTmp != 0)
            {
                llnCurr = llnCurr.Next;
                intTmp--;
            }

            //交换位置
            Reference refCurrValue = llnCurr.Value;
            Reference refNextValue = llnCurr.Next.Value;
            llnCurr.Next.Value = refCurrValue;
            llnCurr.Value = refNextValue;
            
            //刷新表格
            RefreshReferenceData();

            //选中交换前选中的行（否则会默认选中第0行）
            dgvReferenceData.Rows[intNum + 1].Selected = true;

            isModified = true;
        }

        #endregion
    }
};